//
//  KoiNetBase.swift
//  KoiAccounting
//
//  Created by 纪洪文 on 19.03.25.
//

import Foundation
import Alamofire

class KoiNetBase {
    #if DEBUGLOCAL
    static let HOST = "http://192.168.31.5:8000/"
    #else
    static let HOST = "https://api.koiaccounting.com/"
    #endif
    
    static let baseShared = KoiNetBase()
    
    let session = Session()
    let credential = KoiAuthenticationCredential()
    let authenticator = KoiAuthenticator()
    let authInterceptor : AuthenticationInterceptor<KoiAuthenticator>

    init () {
        authInterceptor = AuthenticationInterceptor(authenticator: authenticator, credential: credential)
        
    }
    
    // 同步请求
    func requestAuth<Data: Codable>(path: String, method: HTTPMethod = .get, parameters: Parameters? = nil, headers: HTTPHeaders? = nil) -> Result<Data?, KoiNetError> {
        var resultData : Result<Data?, KoiNetError> = .failure(KoiNetError.httpFailure(AFError.explicitlyCancelled))
        let semaphore = DispatchSemaphore(value: 0)
        request(path: path, method: method, parameters: parameters, headers: headers, interceptor: authInterceptor) { ( result : Result<Data?, KoiNetError>) in
            resultData = result
            semaphore.signal()
        }
        semaphore.wait()
        return resultData
    }
    
    func requestAuth<Data: Codable>(path: String, method: HTTPMethod = .get, parameters: Parameters? = nil, headers: HTTPHeaders? = nil, result:@escaping (Result<Data?, KoiNetError>) -> Void ) {
        request(path: path, method: method, parameters: parameters, headers: headers, interceptor: authInterceptor, result: result)
    }
    
    func requestLogin<Data: Codable>(path: String, method: HTTPMethod = .get, parameters: Parameters? = nil, headers: HTTPHeaders? = nil, result:@escaping (Result<Data?, KoiNetError>) -> Void ) {
        request(path: path, method: method, parameters: parameters, headers: headers, interceptor: nil, result: result)
    }
    
    func request<Data: Codable>(path: String, method: HTTPMethod = .get, parameters: Parameters? = nil, headers: HTTPHeaders? = nil, interceptor: (any RequestInterceptor)? = nil, result:@escaping (Result<Data?, KoiNetError>) -> Void ) {
        AF.request(KoiNetBase.HOST + path, method: method, parameters: parameters, headers: headers, interceptor: interceptor)
            .validate()
            .responseDecodable { (response:AFDataResponse<KoiNetResponse<Data>>) in
                switch(response.result) {
                case .success(let koiResponse):
                    if (koiResponse.isSuccess()) {
                        result(Result.success(koiResponse.data))
                    } else {
                        result(Result.failure(KoiNetError.businessFailure(koiResponse.msg, koiResponse.code)))
                    }
                case .failure(let error):
                    result(Result.failure(KoiNetError.httpFailure(error)))
                }
            }
    }
    
}
